package org.dromara.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.ReportChartBo;
import org.dromara.system.domain.pojo.*;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.*;
import org.dromara.system.service.IDeviceGroupService;
import org.dromara.system.service.ISensorService;
import org.dromara.system.service.ISysSystemReportService;
import org.dromara.system.utils.NoticeUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 岗位信息 服务层处理
 *
 * @author Lion Li
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class SysSystemReportServiceImpl implements ISysSystemReportService {

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private final SysSystemReportMapper baseMapper;
    private final DeviceGroupMapper deviceGroupMapper;
    private final DeviceAlarmMapper deviceAlarmMapper;
    private final ISensorService sensorService;
    private final DeviceMapper deviceMapper;
    private final VariableAssociationMapper variableAssociationMapper;

    private final IDeviceGroupService deviceGroupService;

    public static AlarmStatisticsVo processData(Map<String, Map<String, Object>> data) {
        AlarmStatisticsVo vo = new AlarmStatisticsVo();
        List<String> names = new ArrayList<>();
        List<Long> values = new ArrayList<>();

        // 定义一周的顺序
        List<String> weekDaysOrder = Arrays.asList("周一", "周二", "周三", "周四", "周五", "周六", "周日");

        // 按照定义的顺序排序 data
        List<Map.Entry<String, Map<String, Object>>> sortedEntries = data.entrySet().stream()
                .sorted((e1, e2) -> weekDaysOrder.indexOf(e1.getKey()) - weekDaysOrder.indexOf(e2.getKey()))
                .collect(Collectors.toList());

        for (Map.Entry<String, Map<String, Object>> entry : sortedEntries) {
            String weekDay = entry.getKey();
            names.add(weekDay);
            Map<String, Object> dayData = entry.getValue(); // 获取当前周天的数据
            values.add(convertToLong(dayData.get("total_tunnel_1")));
            values.add(convertToLong(dayData.get("total_tunnel_2")));
            values.add(convertToLong(dayData.get("total_tunnel_3")));
        }

        vo.setDate(names);
        vo.setValue(values);
        return vo;
    }

    private static Long convertToLong(Object value) {
        if (value instanceof BigDecimal) {
            return ((BigDecimal) value).longValue();
        } else if (value instanceof Long) {
            return (Long) value;
        } else {
            throw new IllegalArgumentException("Unsupported type: " + value.getClass().getName());
        }
    }

    public static void setCorrectStatusText(Child child, int status) {
        String name = child.getName();
        if (name.contains("BRKER")) {
            child.setName("断路器状态");
            child.setStatusText(status == 0 ? "正常" : "异常");
        } else if (name.contains("B_S")) {
            child.setName("反转状态");
            child.setStatusText(status == 0 ? "反转" : "正转");
        } else if (name.contains("FAULT")) {
            child.setName("故障状态");
            child.setStatusText(status == 0 ? "正常" : "异常");
        } else if (name.contains("F_S")) {
            child.setName("正转状态");
            child.setStatusText(status == 0 ? "正转" : "反转");
        } else if (name.contains("LOCAL")) {
            child.setName("就地状态");
            child.setStatusText(status == 0 ? "就地" : "未就地");
        }
    }


    @Override
    public void addReport() {
        Date currentDate = new Date();
        ObjectMapper objectMapper = new ObjectMapper();
        Calendar calendar1 = Calendar.getInstance();
        // 减去一天
        calendar1.add(Calendar.DAY_OF_YEAR, -1);
        // 获取昨天的日期
        Date yesterdayDate = calendar1.getTime();
        // 获取昨天的起始时间和结束时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calendar.getTime();

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calendar.getTime();

        try {
            // 获取所有父节点 channel_id
            List<Long> parentIds = Arrays.asList(1L, 2L, 3L);

            for (Long channelId : parentIds) {
                // 获取该 channelId 下的设备组
                List<DeviceGroupVo> groupList = deviceGroupMapper.selectVoList(
                        new LambdaQueryWrapper<DeviceGroup>().eq(DeviceGroup::getParentId, channelId)
                );

                if (groupList == null || groupList.isEmpty()) {
                    continue; // 跳过没有设备组的 channel_id
                }

                List<Report> reportList = new ArrayList<>();
                for (DeviceGroupVo group : groupList) {
                    // 获取设备组的所有子节点 ID，并去重
                    Set<Long> allSubNodeIds = new HashSet<>(deviceGroupMapper.findAllSubNodeIds(group.getId()));
                    if (allSubNodeIds == null || allSubNodeIds.isEmpty()) {
                        continue;
                    }

                    // 查询报警数据
                    Long count = deviceAlarmMapper.selectCount(new LambdaQueryWrapper<DeviceAlarm>()
                            .eq(DeviceAlarm::getStatus, 0)
                            .in(DeviceAlarm::getDeviceGroup, allSubNodeIds)
                            .between(DeviceAlarm::getCreateTime, startOfDay, endOfDay)
                    );

                    Report report = new Report();
                    report.setId(group.getId());
                    report.setName(group.getGroupName());
                    report.setCount(count != null ? count : 0L); // 确保 count 不为 null
                    reportList.add(report);
                }
                // 格式化日期
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String formattedDate = sdf.format(yesterdayDate);
                // 创建 SysSystemReport
                SysSystemReport sysSystemReport = new SysSystemReport();
                sysSystemReport.setTitle(formattedDate + "系统报告");
                sysSystemReport.setChannelId(channelId); // 设置 channel_id

                sysSystemReport.setRecordDate(formattedDate);

                sysSystemReport.setCreateTime(new Date()); // 设置当前时间为 create_time

                // 获取设备报警总数
                Long deviceCount = deviceAlarmMapper.selectReportCount();
                sysSystemReport.setAlarmDeviceCount(deviceCount);
                Long re = deviceAlarmMapper.selectRecoverCount();
                sysSystemReport.setRecoverCount(re);
                sysSystemReport.setDescription("昨天发生了" + deviceCount + "报警,目前已恢复了" + re + "台设备");

                try {
                    String json = objectMapper.writeValueAsString(reportList);
                    sysSystemReport.setData(json);
                } catch (JsonProcessingException e) {
                    sysSystemReport.setData("[]"); // 设置为空 JSON
                }

                // 插入数据库
                int result = baseMapper.insert(sysSystemReport);
                if (result <= 0) {
                    throw new RuntimeException("Failed to insert sysSystemReport into database for channel_id: " + channelId);
                }

                // 获取昨日的报警id集合
                List<Long> alarmIds = deviceAlarmMapper.selectAlarmIds(startOfDay, endOfDay);

                if (alarmIds != null && !alarmIds.isEmpty()) {
                    // 插入关联表
                    try {
                        baseMapper.insertAlarmReport(sysSystemReport.getId(), alarmIds);
                    } catch (Exception e) {
                        log.error("Failed to insert alarm report for sysSystemReport ID: {}", sysSystemReport.getId(), e);
                    }
                }

            }
        } catch (Exception e) {
            throw new RuntimeException("Error occurred while adding report", e);
        }
    }



    @Override
    public List<ReportChart> getReportChart(ReportChartBo bo) {
        List<ReportChart> list;
        LambdaQueryWrapper<SysSystemReport> lqw = new LambdaQueryWrapper<>();

        // 设置查询条件
        setQueryConditions(lqw, bo);

        // 执行查询
        List<SysSystemReportVo> sysSystemReportVos = baseMapper.selectVoList(lqw);

        // 转换查询结果
        list = sysSystemReportVos.stream()
                .map(this::convertToReportChart)
                .collect(Collectors.toList());

        return list;
    }

    @Override
    public DataVo getReportNum() {
        Long count = sensorService.selectCountReportData();
        DataVo dataVo = new DataVo();
        dataVo.setTotal(count);
        return dataVo;
    }

    @Override
    public List<DeviceStatisticsByScreenVo> deviceStatistics(Long tunnelId) {
        if (tunnelId == null) {
            tunnelId = 2L;
        }
        List<DeviceGroup> deviceGroups = fetchDeviceGroupsByParentId(tunnelId);
        List<DeviceStatisticsByScreenVo> deviceStatisticsVos = new ArrayList<>();

        for (DeviceGroup deviceGroup : deviceGroups) {
            DeviceStatisticsByScreenVo statisticsVo = createDeviceStatisticsVo(deviceGroup);
            deviceStatisticsVos.add(statisticsVo);
        }

        return deviceStatisticsVos;
    }

    private List<DeviceGroup> fetchDeviceGroupsByParentId(Long parentId) {
        return deviceGroupMapper.selectList(
            new LambdaQueryWrapper<DeviceGroup>().in(DeviceGroup::getParentId, parentId)
        );
    }

    private DeviceStatisticsByScreenVo createDeviceStatisticsVo(DeviceGroup deviceGroup) {
        DeviceStatisticsByScreenVo deviceStatisticsVo = new DeviceStatisticsByScreenVo();
        List<Long> allSubNodeIds = findAllSubNodeIds(deviceGroup.getId());
        Long count = countDevicesByGroupIds(allSubNodeIds);

        deviceStatisticsVo.setCount(count);
        deviceStatisticsVo.setName(deviceGroup.getGroupName());
        deviceStatisticsVo.setId(deviceGroup.getId());

        return deviceStatisticsVo;
    }

    private List<Long> findAllSubNodeIds(Long groupId) {
        return deviceGroupMapper.findAllSubNodeIds(groupId);
    }

    private Long countDevicesByGroupIds(List<Long> groupIds) {
        return deviceMapper.selectCount(
            new LambdaQueryWrapper<Device>().in(Device::getGroupId, groupIds)
        );
    }

    @Override
    public VariableData paramStatistics() {
        VariableData variableData = new VariableData();
        variableData.setTotal(variableAssociationMapper.selectCount(new LambdaQueryWrapper<>()));
        variableData.setSwitchTotal(variableAssociationMapper.selectCount(new LambdaQueryWrapper<VariableAssociation>().eq(VariableAssociation::getVariableType, 1)));
        variableData.setSensorTotal(variableAssociationMapper.selectCount(new LambdaQueryWrapper<VariableAssociation>().eq(VariableAssociation::getVariableType, 2)));
        return variableData;
    }

    @Override
    public List<ParamTotalStatistics> paramTotalStatistics() {
        List<ParamTotalStatistics> paramTotalStatistics = new ArrayList<>();
        Map<String, Long> tunnelMap = getTunnelMap();
        for (Map.Entry<String, Long> entry : tunnelMap.entrySet()) {
            ParamTotalStatistics paramTotalStatisticsVo = new ParamTotalStatistics();
            paramTotalStatisticsVo.setName(entry.getKey());
            paramTotalStatisticsVo.setTunnelId(entry.getValue());
            paramTotalStatisticsVo.setCount(getParamTotalStatistics(entry.getValue()));
            paramTotalStatistics.add(paramTotalStatisticsVo);
        }
        paramTotalStatistics.sort(Comparator.comparingLong(ParamTotalStatistics::getTunnelId));
        return paramTotalStatistics;
    }
    private Long getParamTotalStatistics(Long tunnelId){
        if (tunnelId == 1L){
           return sensorService.getYtDataCount();
        } else if (tunnelId == 2L) {
            return sensorService.getDhmDataCount();
        }else {
            return sensorService.getFiveDataCount();
        }
    }


    @Override
    public List<ParamTotalStatistics> todayAlarm() {
        // 定义隧道名称和对应的隧道ID
        Map<String, Long> tunnelMap = new HashMap<>();
        tunnelMap.put("应天大街隧道", 1L);
        tunnelMap.put("定淮门隧道", 2L);
        tunnelMap.put("江心洲大桥", 3L);
        List<ParamTotalStatistics> paramTotalStatistics = new ArrayList<>();
        for (Map.Entry<String, Long> entry : tunnelMap.entrySet()) {
            ParamTotalStatistics paramTotalStatisticsVo = new ParamTotalStatistics();
            paramTotalStatisticsVo.setName(entry.getKey());
            paramTotalStatisticsVo.setTunnelId(entry.getValue());
            paramTotalStatisticsVo.setTunnelName(entry.getKey());

            LambdaQueryWrapper<DeviceAlarm> queryWrapper = new LambdaQueryWrapper<DeviceAlarm>()
                    .eq(DeviceAlarm::getStatus, 0)
                    .eq(DeviceAlarm::getTunnelId, entry.getValue());

            paramTotalStatisticsVo.setCount(deviceAlarmMapper.selectCount(queryWrapper));
            paramTotalStatistics.add(paramTotalStatisticsVo);
        }
        //按照id 升序
        paramTotalStatistics.sort(Comparator.comparingLong(ParamTotalStatistics::getTunnelId));
        return paramTotalStatistics;
    }



    @Override
    public WeekData alarmStatistics() {
        List<AlarmStatisticsVo> alarmStatisticsVos = new ArrayList<>();
        Map<String, Map<String, Object>> stringObjectMap = baseMapper.selectValue();
        AlarmStatisticsVo alarmStatisticsVo = processData(stringObjectMap);
        alarmStatisticsVos.add(alarmStatisticsVo);

        // 将 AlarmStatisticsVo 转换为 WeekData
        WeekData weekData = convertToWeekData(alarmStatisticsVo);
        return weekData;
    }

    public WeekData convertToWeekData(AlarmStatisticsVo alarmStatisticsVo) {
        WeekData weekData = new WeekData();
        weekData.setDate(alarmStatisticsVo.getDate());

        List<TunnelData> tunnelDataList = new ArrayList<>();

        // 假设每个隧道的数据长度与日期列表相同
        int numTunnels = 3;
        int numDays = alarmStatisticsVo.getDate().size();

        for (int i = 0; i < numTunnels; i++) {
            TunnelData tunnelData = new TunnelData();
            tunnelData.setId(i + 1);

            tunnelData.setName(deviceGroupService.getGroupName(Long.valueOf(i + 1)));
            List<Long> tunnelValues = new ArrayList<>();
            for (int j = 0; j < numDays; j++) {
                tunnelValues.add(alarmStatisticsVo.getValue().get(j * numTunnels + i));
            }
            tunnelData.setData(tunnelValues);
            tunnelDataList.add(tunnelData);
        }

        weekData.setData(tunnelDataList);
        return weekData;
    }


    @Override
    public List<ParamTotalStatistics> sysSystemReportService() {
        List<ParamTotalStatistics> paramTotalStatistics = new ArrayList<>();
        List<Params> list = deviceGroupMapper.sysSystemReportService();
//        List<DeviceGroup> deviceGroupVoList = deviceGroupMapper.selectList(new LambdaQueryWrapper<DeviceGroup>().in(DeviceGroup::getId, Arrays.asList(20L, 27L, 17L)));
        for (Params deviceGroup : list) {
            ParamTotalStatistics paramTotalStatisticsVo = new ParamTotalStatistics();
            paramTotalStatisticsVo.setName(deviceGroupMapper.getGroupNameById(deviceGroup.getDeviceGroup()));
            paramTotalStatisticsVo.setCount(deviceGroup.getCount());
            paramTotalStatisticsVo.setTunnelName(deviceGroupMapper.getGroupNameById(deviceGroupService.getRootNodeId(deviceGroup.getDeviceGroup())));
            paramTotalStatistics.add(paramTotalStatisticsVo);
        }
        return paramTotalStatistics;
    }

    private DeviceGroupVo traceToTopNodes(Long selectedId) {
        List<DeviceGroupVo> allNodes = deviceGroupMapper.selectVoList();
        Map<Long, DeviceGroupVo> idToNodeMap = allNodes.stream()
                .collect(Collectors.toMap(DeviceGroupVo::getId, Function.identity()));

        DeviceGroupVo currentNode = idToNodeMap.get(selectedId);
        while (currentNode.getParentId() != 0) {
            currentNode = idToNodeMap.get(currentNode.getParentId());
        }
        return currentNode;
    }

    @Override
    public List<TunnelStats> importantDevice() {
        List<TunnelStats> tunnelStats = new ArrayList<>();
        Map<String, Long> tunnelMap = getTunnelMap();
        for (Map.Entry<String, Long> entry : tunnelMap.entrySet()) {
            TunnelStats tunnelStatsVo = getDeviceCount(entry.getValue());
            tunnelStatsVo.setTunnelId(entry.getValue());
            tunnelStatsVo.setAbnormalCount(tunnelStatsVo.getFaultCount());
            tunnelStatsVo.setForwardStateCount(0L);
            tunnelStatsVo.setReverseStateCount(0L);
            tunnelStatsVo.setLocalCount(0L);
            tunnelStatsVo.setNotLocalCount(0L);
            tunnelStats.add(tunnelStatsVo);
        }
        tunnelStats.sort(Comparator.comparing(TunnelStats::getTunnelId));
        return tunnelStats;
    }


    /**
     * 隧道idh和name绑定
     * @return
     */
    private Map<String, Long> getTunnelMap() {
        Map<String, Long> tunnelMap = new HashMap<>();
        tunnelMap.put("应天大街隧道", 1L);
        tunnelMap.put("定淮门隧道", 2L);
        tunnelMap.put("江心洲大桥", 3L);
        return tunnelMap;
    }

    /**
     * 隧道id和分组id绑定
     * @return
     */
    private Map<Long, Long> getGroupIdMap() {
        Map<Long, Long> groupIdMap = new HashMap<>();
        groupIdMap.put(1L, 85L);
        groupIdMap.put(2L, 14L);
        groupIdMap.put(3L, 0L);
        return groupIdMap;
    }

    private TunnelStats getDeviceCount(Long tunnelId) {
        Map<Long, Long> groupIdMap = getGroupIdMap();
        if (groupIdMap.containsKey(tunnelId)) {
            Long groupId = groupIdMap.get(tunnelId);
            List<Long> allSubNodeIds = deviceGroupMapper.findAllSubNodeIds(groupId);
            TunnelStats tunnelStats = deviceMapper.selectReverseAndForwardCount(tunnelId, allSubNodeIds);
            tunnelStats.setFaultCount(selectFaultCount(tunnelId,allSubNodeIds));
            return tunnelStats;
        } else {
            // 处理未知的 tunnelId 情况
            throw new IllegalArgumentException("Unknown tunnelId: " + tunnelId);
        }
    }

    public Long selectFaultCount(Long tunnelId, List<Long> groupIds) {
        if (groupIds == null || groupIds.isEmpty()) {
            // 处理 groupIds 为空的情况，例如返回 0 或者抛出异常
            return 0L;
        }
        return deviceMapper.selectFaultCount(tunnelId, groupIds);
    }



    @Override
    public NoticeVo maintenancePlan() {
        return NoticeUtils.getNoticeInfo();

    }

    @Override
    public void setMaintenancePlan(NoticeVo noticeVo) {
        NoticeUtils.setTitle(noticeVo.getTitle());
    }

    @Override
    public DeviceAlarmVo alarmLatest() {
        DeviceAlarmVo deviceAlarmVo = deviceAlarmMapper.selectVoOne(new LambdaQueryWrapper<DeviceAlarm>().eq(DeviceAlarm::getStatus, 0).orderByDesc(DeviceAlarm::getCreateTime).orderByDesc(DeviceAlarm::getId).last("LIMIT 1"));
        if (deviceAlarmVo == null) return new DeviceAlarmVo();
        return deviceAlarmVo;
    }

    @Override
    public DashVo getReportInfo(ReportChartBo bo) {
        DashVo dashVo = new DashVo();
        dashVo.setDataCount(sensorService.selectYeasCount());
        // 设置隧道数量和设备总数
        dashVo.setTunnelCount(deviceGroupMapper.selectCount(new LambdaQueryWrapper<DeviceGroup>().eq(DeviceGroup::getParentId, 0)));
        dashVo.setDeviceCount(baseMapper.selectCount(new LambdaQueryWrapper<>()));

        // 根据 bo.getTunnelId() 是否为空，选择不同的查询条件
        Long tunnelId = bo.getTunnelId();
        LambdaQueryWrapper<Device> deviceWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<DeviceAlarm> alarmWrapper = new LambdaQueryWrapper<>();

        if (tunnelId != null) {
            deviceWrapper.eq(Device::getTunnelId, tunnelId);
            alarmWrapper.eq(DeviceAlarm::getTunnelId, tunnelId);
        }
        if (bo.getDate() != null) {
            //DATE_FORMATTER
            LocalDate startDate = LocalDate.parse(bo.getDate(), DATE_FORMATTER);
            LocalDate endDate = LocalDate.parse(bo.getDate(), DATE_FORMATTER);
            alarmWrapper.between(DeviceAlarm::getCreateTime, startDate.atStartOfDay(), endDate.atTime(23, 59, 59));

        }

        // 设置设备状态和报警数量
        setDeviceCounts(dashVo, deviceWrapper);
        setAlarmCounts(dashVo);
        dashVo.setAlarmALLCount(deviceAlarmMapper.selectAllCount());

        return dashVo;
    }

    private void setDeviceCounts(DashVo dashVo, LambdaQueryWrapper<Device> deviceWrapper) {
        // 获取正常设备数量
        Long normalDeviceCount = getYesterdayAlarmCount();
        dashVo.setNormalDeviceCount(normalDeviceCount != null ? normalDeviceCount : 0);

        // 获取异常设备数量
        Long abnormalDeviceCount = deviceMapper.selectCount(deviceWrapper.eq(Device::getStatus, 1));
        dashVo.setAbnormalDeviceCount(abnormalDeviceCount != null ? abnormalDeviceCount : 0);
    }

    private void setAlarmCounts(DashVo dashVo) {
        // 获取报警数量
        dashVo.setAlarmCount(getTodayAlarmCount());

        // 获取已处理报警数量
        Long alarmHandleCount =getTodayAlarmHandleCount();
        dashVo.setAlarmHandleCount(alarmHandleCount != null ? alarmHandleCount : 0);

        // 获取未处理报警数量
        Long alarmUnprocessedCount = deviceAlarmMapper.selectAlarmCount();
        dashVo.setAlarmUnprocessedCount(alarmUnprocessedCount != null ? alarmUnprocessedCount : 0);
    }

    /**
     * 获取昨日的报警数量
     * @return 昨日的报警数量
     */
    public Long getYesterdayAlarmCount() {
        // 获取昨天的日期
        LocalDate yesterday = LocalDate.now().minusDays(1);

        // 计算昨天的开始时间（00:00:00）
        LocalDateTime startOfYesterday = yesterday.atStartOfDay();

        // 计算昨天的结束时间（23:59:59.999999999）
        LocalDateTime endOfYesterday = yesterday.atTime(LocalTime.MAX);

        // 构建查询条件
        LambdaQueryWrapper<DeviceAlarm> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceAlarm::getStatus, 0)
            .between(DeviceAlarm::getCreateTime, startOfYesterday, endOfYesterday);

        // 执行查询并返回结果
        return deviceAlarmMapper.selectCount(queryWrapper);
    }


    /**
     * 获取今天的报警数量
     * @return
     */
    public Long getTodayAlarmCount() {
        // 获取当前日期
        LocalDate today = LocalDate.now();

        // 计算今天的开始时间（00:00:00）
        LocalDateTime startOfDay = today.atStartOfDay();

        // 计算今天的结束时间（23:59:59.999999999）
        LocalDateTime endOfDay = today.atTime(LocalTime.MAX);

        // 构建查询条件
        LambdaQueryWrapper<DeviceAlarm> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceAlarm::getStatus, 0)
            .between(DeviceAlarm::getCreateTime, startOfDay, endOfDay);

        // 执行查询并返回结果
        return deviceAlarmMapper.selectCount(queryWrapper);
    }

    /**
     * 获取今天的已处理报警数量
     * @return
     */
    public Long getTodayAlarmHandleCount() {
        // 获取当前日期
        LocalDate today = LocalDate.now();

        // 计算今天的开始时间（00:00:00）
        LocalDateTime startOfDay = today.atStartOfDay();

        // 计算今天的结束时间（23:59:59.999999999）
        LocalDateTime endOfDay = today.atTime(LocalTime.MAX);

        // 构建查询条件
        LambdaQueryWrapper<DeviceAlarm> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceAlarm::getStatus, 1)
            .between(DeviceAlarm::getCreateTime, startOfDay, endOfDay);
        // 执行查询并返回结果
        return deviceAlarmMapper.selectCount(queryWrapper);
    }


    @Override
    public TableDataInfo<DeviceAlarmVo> getReportAlarm(ReportChartBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<DeviceAlarm> lqw = new LambdaQueryWrapper<>();

        if (bo.getTunnelId() != null) {
            lqw.in(DeviceAlarm::getTunnelId, bo.getTunnelId());
        }

        if (bo.getMode() != null) {
            switch (bo.getMode()) {
                case 1:
                    if (StringUtils.isNotBlank(bo.getDate())) {
                        LocalDate date = LocalDate.parse(bo.getDate(), DATE_FORMATTER);
                        LocalDateTime startOfDay = date.atStartOfDay();
                        LocalDateTime endOfDay = date.atTime(LocalTime.MAX);
                        lqw.between(DeviceAlarm::getCreateTime, startOfDay, endOfDay);
                    }
                    break;
                case 2:
                    // 今日报警
                    addTimeRangeToQuery(lqw, LocalDate.now());
                    lqw.eq(DeviceAlarm::getStatus, 0);
                    break;
                case 3:
                    // 今日已解除报警
                    addTimeRangeToQuery(lqw, LocalDate.now());
                    lqw.eq(DeviceAlarm::getStatus, 1);
                    break;
                case 4:
                    lqw.eq(DeviceAlarm::getStatus, 0);
                    break;
                default:
                    // 处理未知模式的情况
                    throw new IllegalArgumentException("Unknown mode: " + bo.getMode());
            }
        } else {
            if (StringUtils.isNotBlank(bo.getDate())) {
                LocalDate date = LocalDate.parse(bo.getDate(), DATE_FORMATTER);
                addTimeRangeToQuery(lqw, date);
            }
        }

        Page<DeviceAlarmVo> result = deviceAlarmMapper.selectVoPage(pageQuery.build(), lqw);
        if (!result.getRecords().isEmpty()) {
            for (DeviceAlarmVo record : result.getRecords()) {
                record.setDeviceGroupName(deviceAlarmMapper.selectDeviceGroupNameById(record.getDeviceGroup()));
            }
        }

        return TableDataInfo.build(result);
    }

    private void addTimeRangeToQuery(LambdaQueryWrapper<DeviceAlarm> lqw, LocalDate date) {
        LocalDateTime startOfDay = date.atStartOfDay();
        LocalDateTime endOfDay = date.atTime(LocalTime.MAX);
        lqw.between(DeviceAlarm::getCreateTime, startOfDay, endOfDay);
    }


    @Override
    public TableDataInfo<SysSystemReportVo> getReportLogList(ReportChartBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysSystemReport> lqw = new LambdaQueryWrapper<>();
        if (bo.getTunnelId() != null) {
            lqw.in(SysSystemReport::getChannelId, bo.getTunnelId());
        }

        if (StringUtils.isNotBlank(bo.getDate())) {
            LocalDate date = LocalDate.parse(bo.getDate(), DATE_FORMATTER);
            LocalDateTime startOfDay = date.atStartOfDay();
            LocalDateTime endOfDay = date.atTime(23, 59, 59);
            // 设置 bo 的日期，这里不需要再解析一次
            bo.setDate(date.toString());
            lqw.between(SysSystemReport::getCreateTime, startOfDay, endOfDay);
        }
        Page<SysSystemReportVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    private void setQueryConditions(LambdaQueryWrapper<SysSystemReport> lqw, ReportChartBo bo) {
        if (StringUtils.isNotBlank(bo.getDate())) {
            lqw.eq(SysSystemReport::getRecordDate, bo.getDate());
        } else {
            lqw.eq(SysSystemReport::getRecordDate, getCurrentDate());
        }
        if (bo.getTunnelId() != null) {
            lqw.eq(SysSystemReport::getChannelId, bo.getTunnelId());
        }
    }

    private String getCurrentDate() {
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(currentDate);
    }

    private ReportChart convertToReportChart(SysSystemReportVo sysSystemReportVo) {
        ReportChart reportChart = new ReportChart();
        reportChart.setId(sysSystemReportVo.getId());
        reportChart.setRecordDate(sysSystemReportVo.getRecordDate());
        reportChart.setChannelId(sysSystemReportVo.getChannelId());
        ObjectMapper objectMapper = new ObjectMapper();
        // 注册 JavaTimeModule 以支持 LocalDate 的解析
        objectMapper.registerModule(new JavaTimeModule());

        try {
            // 将 JSON 字符串解析为 List<Report>
            List<Report> statistics = objectMapper.readValue(
                    sysSystemReportVo.getData(),
                    objectMapper.getTypeFactory().constructCollectionType(List.class, Report.class)
            );
            reportChart.setStatistics(statistics);
        } catch (JsonProcessingException e) {
            // 如果解析失败，记录日志并设置默认值
            reportChart.setStatistics(Collections.emptyList()); // 设置为空列表
        }

        return reportChart;
    }


}

